//
// Created by LiuYou on 2021/7/23.
//

#include "HasPtrLikeValue.hpp"

/// \brief CLion生成的构造函数。
/*ResourceManagement::HasPtrLikeValue::HasPtrLikeValue(std::string* ptrString, int defaultValue) :
        ptrString( ptrString ), defaultValue( defaultValue ) {}*/

/// \brief 书上的写法。
/// \param str
///
/// 这里书上的写法, 我觉得是初始化类管理的资源(类的成员变量/类的字段)的两种思路:
// 要么是使用类的人在首次创建类的时候向显式的构造函数传递参数。即CLion使用的生成构造函数代码时的方式。
// 要么是直接在类内字段定义处就初始化或者在构造函数的初始值列表中对外不显示的即隐式的构造。书中就是这样的。
// 总之两种方法都行。
ResourceManagement::HasPtrLikeValue::HasPtrLikeValue(const std::string& str) :
        ptrString( new std::string( str )), defaultValue( 0 ) {}


ResourceManagement::HasPtrLikeValue::~HasPtrLikeValue() {
    delete ptrString;
}


/// \brief CLion是不会自己生成拷贝构造函数, 需要自己写。这个写法是书上的写法。
/// \param rhs
ResourceManagement::HasPtrLikeValue::HasPtrLikeValue(const ResourceManagement::HasPtrLikeValue& rhs) :
        ptrString( new std::string( *rhs.ptrString )), defaultValue( rhs.defaultValue ) {}


ResourceManagement::HasPtrLikeValue&
ResourceManagement::HasPtrLikeValue::operator=(ResourceManagement::HasPtrLikeValue rhs) {
    swap( *this, rhs );
    return *this;
}


/// \brief 同样CLion是不会自己生成拷贝构造函数, 需要自己写。这个写法是书上的写法。
/// \param hasPtrLikeValue
/// \return
//ResourceManagement::HasPtrLikeValue&
//ResourceManagement::HasPtrLikeValue::operator=(const ResourceManagement::HasPtrLikeValue& rhs) {
//    //<editor-fold desc="之前的版本, 这个版本是正确的, 但是可以再改进。">
////    std::string* pString = new std::string( *rhs.ptrString );
////    delete ptrString;
////    ptrString = pString;
////    defaultValue = rhs.defaultValue;
////    return *this;
//    //</editor-fold>
//
//    //<editor-fold desc="改进后的版本">
//    if (&rhs == this) {
////        std::fprintf( stdout, "自我赋值检查, 该操作是自我赋值。" );
//        return *this;
//    }
//    std::string* pString = new std::string( *rhs.ptrString );
//    delete ptrString;
//    ptrString = pString;
//    defaultValue = rhs.defaultValue;
//    return *this;
//    //</editor-fold>
//}


/// \brief 以后不会将流输出函数写在类外了。
//std::ostream& ResourceManagement::operator<<(std::ostream& os, const ResourceManagement::HasPtrLikeValue& value) {
//    os << "ptrString: " << value.ptrString
//       << " *ptrString: " << *value.ptrString
//       << " defaultValue: " << value.defaultValue;
//    return os;
//}
